/**
 * IFacade 是框架的管理者和通信中心
 * 是框架与外界通信的唯一接口
 * 负责初始化 model view controller
 * 发送通知
 */
export interface IFacade extends INotifier {

  //====与controller层交互
  //增
  registerCommand(notificationName: string, commandClassRes: Function): void;
  //删
  removeCommand(notificationName: string): void;
  //判断是否存在command类
  hasCommand(notificationName: string): boolean;

  //==== 与model层的交互
  //增
  registerProxy(proxy: IProxy): void;
  //查
  retrieveProxy(proxyName: string): IProxy;
  //删
  removeProxy(proxyName: string): IProxy;
  //是否存在
  hasProxy(proxyName: string): boolean;

  //=== 与view 层的交互
  //增
  registerMediator(mediator: IMediator): void;
  //查
  retrieveMediator(mediatorName: string): IMediator;
  //删
  removeMediator(mediatorName: string): IMediator;
  //是否已存在
  hasMediator(mediatorName: string): boolean;

  //=== 与observer的交互，实现通信机制
  //创建并发送一个通知，这样
  //我们在实现代码中，就不用再创建通知实例了
  sendNotification(name: string, body: any, type: string): void;
  //公开这个方法，主要是为了向下兼容，允许
  //你使用facade发送自定义通知。通常，你可
  //只调用sendNotice方法，根本不需要自己
  //创建通知
  notifyObservers(notification: INotification): void;
}
 /**
 * IModel 负责保存proxy名称与实例的映射
 * 根据proxy名称获取其实例
 */
export interface IModel {
  //增
  registerProxy(proxy: IProxy): void;
  //删
  removeProxy(proxyName: string): IProxy;
  //查
  retrieveProxy(proxyName: string): IProxy;
  //是否已存在
  hasProxy(proxyName: string): boolean;
}
/**
 * IView 负责保存mediator名称与实例的映射
 * 通知 名称与观察者的映射
 * 根据mediator名称获取其实例
 * 根据notice 通知 其观察者
 */
export interface IView {
  //把observer存入观察者列表中，收到通知，
  //就遍历对应的观察者列表，通知各个observe
  registerObserver(notificationName: string, observer: IObserver): void;
  //从观察者列表中删除observer
  removeObserver(notificationName: string, notifyContext: any): void;
  //通知notice 的观察者列表中的 所有观察者
  notifyObservers(notification: INotification): void;
  /**
   * 首先把mediator实例赋值个mediatormap的属性
   * mediatorName 作为属性名。然后，通过名称获取
   * mediator实例，并进一步查询它所关注的notice
   * 若返回notice列表，则创建观察者 封装mediator
   * 实例及其handleNotice方法
   * 把观察者注册给列表中每个notice
   * 最后 触发mediator实例的别注册事件
   */
  registerMediator(mediatorName: IMediator): void;
  //查
  retrieveMediator(mediatorName: string): IMediator;
  //删
  removeMediator(mediatorName: string): IMediator;
  //是否已经添加
  hasMediator(mediatorName: string): boolean;
}
 /***
 * IController负责保存notice名称与command类的
 * 映射
 * 执行通知对应的command
 */
export interface IController {
  //执行note对应的command。首先根据note名称
  //获取command类，然后，创建command实例，执行
  //command业务逻辑
  executeCommand(notification: INotification): void;
  //增
  registerCommand(notificationName: string, commandClassRes: Function): void;
  //删
  removeCommand(notificationName: string): void;
  //是否已存在
  hasCommand(notificationName: string): boolean;
}
/**
 * IProxy 是model 的助理 负责保存数据对象
 * 存取数据，看发送通知
 */
export interface IProxy extends INotifier{
  //获取proxy名称
  getProxyName(): string;
  //设置proxy 数据
  setData(data: any): void;
  //获取数据
  getData(): any;
  //创建时
  onRegister(): void;
  //删除时
  onRemove(): void;
}
 /**
 * IMediator是view的助理，负责保存视图组件
 * 操作具体的视图组件，处理通知
 */
export interface IMediator extends INotifier {
  //获取mediator名称
  getMediatorName(): string;
  //获取mediator要处理的视图组件
  getViewComponent(): any;
  //设置 视图组件
  setViewComponent(viewComponent: any): void;
  //列出mediator关注的通知
  listNotificationInterests(): string[];
  //收到通知进行处理
  handleNotification(notification: INotification): void;
  //创建时
  onRegister(): void;
  //删除时
  onRemove():void;
}
/**
 * ICommand是controller的助理
 */
export interface ICommand extends INotifier {
  //执行command
  execute(notification: INotification): void;
  //创建
  initializeNotifier(str: string): void;
}
/**
* IObserver负责保存通知的处理者及处理方法
* 收到通知则告知处理者处理这个通知
*/
export interface IObserver {
  //设置处理函数
  setNotifyMedthod(notifyMedthod: Function): void;
  //设置处理者
  setNotifyContext(notifyContext: any): void;
  //通知notification的处理者
  notifyObserver(notification: INotification): void;
  //判断object 是不是处理者
  compareNotifyContext(object: any): boolean;
}

/**
 * INotifier 负责发送通知。
 */
export interface INotifier {

  //发送通知
  sendNotification(name: string, body?: any, type?: string):void;
  //初始化
  initializeNotifier(key: string): void;
}

/**
 * INotification 负责保存通知的名称，类型，发送者
 * 并提供读写通知名称 类型 发送者的接口
 */
export interface INotification {
  //获取通知名
  getName(): string;
  //设置通知内容
  setBody(body: any): void;
  //获取通知内容
  getBody(): any;
  //设置通知类型
  setType(type: string): void;
  //获取通知类型
  getType(): string;
  //把通知转化为字符串形式
  toString(): string;
}

